import * as THREE from 'three';
import { sideMeshType } from './GreenHouse';

/** 底部造成的Z偏移 */
const baseBottomStep = 400;
const baseBottomSize = 100;
/** 钢结构造成的Z偏移 */
const baseSteelStep = 10;

interface ScaleZParams {
  zScale: number;
  model: THREE.Object3D;
  cloneProofTracker: Editor.ResourceTracker;
}

// TODO: 功能扩展，对于左右面的缩放，需要对湿帘加以处理
export const scaleZStrategy = (params: ScaleZParams) => {
  const { model, zScale, cloneProofTracker } = params;

  /** 左右面，name为1和3 */
  const leftRightStrategy = (mesh: THREE.Mesh) => {
    mesh.scale.setY(baseBottomSize * zScale);
    mesh.position.z = baseSteelStep * (zScale - 1);

    // 贴图重复
    if (mesh.isMesh && Array.isArray(mesh.material)) {
      mesh.material.forEach((mat: THREE.MeshPhongMaterial) => {
        if (mat.map) {
          const texture = mat.map;
          texture.wrapS = THREE.RepeatWrapping;
          texture.wrapT = THREE.RepeatWrapping;
          texture.repeat.setX(zScale);
        }
      });
    }
  };
  /** 后面，name为4 */
  const backStrategy = (mesh: THREE.Mesh) => {
    mesh.position.z = -baseBottomStep * (zScale - 1);
  };
  const bottomStrategy = (mesh: THREE.Mesh) => {
    mesh.scale.setY(baseBottomSize * zScale);
    mesh.position.z = baseSteelStep * (zScale - 1);
  };

  /** FIXME: 每次重新scale时，应该清除这些模型 */
  const topStrategy = (mesh: THREE.Mesh) => {
    for (let i = 0; i < zScale - 1; i++) {
      // 复制一个child模型
      const newChild = mesh.clone();
      newChild.name = `5-${i + 1}`;
      cloneProofTracker.track(newChild);
      model.add(newChild);
      newChild.position.setZ(-baseBottomStep * (i + 1));
    }
  };

  const strategyMap: Record<
    Extract<Editor.SideMeshType, 'left' | 'right' | 'back' | 'bottom' | 'top' | 'leftWetCurtain' | 'rightWetCurtain'>,
    (mesh: THREE.Mesh) => void
  > = {
    [sideMeshType.left]: leftRightStrategy,
    [sideMeshType.leftWetCurtain]: leftRightStrategy,
    [sideMeshType.right]: leftRightStrategy,
    [sideMeshType.rightWetCurtain]: leftRightStrategy,
    [sideMeshType.back]: backStrategy,
    [sideMeshType.bottom]: bottomStrategy,
    [sideMeshType.top]: topStrategy,
  };

  model.traverse((child: THREE.Mesh) => {
    if (child.isMesh && child.name) {
      const scaleZStrategy = strategyMap[child.name];
      if (typeof scaleZStrategy === 'function') {
        scaleZStrategy(child);
      }
    }
  });
};
